//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "A2_Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TmyForm *myForm;
//---------------------------------------------------------------------------
__fastcall TmyForm::TmyForm(TComponent* Owner)
  : TForm(Owner)
{
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::OpenBinaryTextData1Click(TObject *Sender)
{
  char buf[256],
       *p;
  long fsize;
  LONG valu,
       cmpv;
  LONG cIndex;
  WORD pointer;
  FILE *tf;

  LONG offset;
  LONG lpPosi;
  int  count;

  Open1->Title      = "Open ROM File";
  Open1->Filter     = "SNES ROM | *.s*c; *.fig;";
  Open1->InitialDir = cur_dir;
  //
  if ( Open1->Execute( ) )
  { // Create Dump directory!
    getcwd( dirc, MAXPATH );
    strcat( dirc, "/Dumps" );
    mkdir( dirc );

    //
    strcpy(romf, Open1->FileName.c_str( ) );
    tf = fopen( romf, "rb" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open file!");
      return;
    }
    //
    _free( rom );
    rom = (BYTE *)malloc( fsize = FileSize( tf ) );
    //
    if ( !rom ){
      fclose( tf );
      ShowMessage( "Fatal Error: Could not allocate needed memory!" );
      Close( );
    }

    // Check for dumb header
    if ( fsize & 0x0200 ){
      fsize -= 0x0200;
      fseek( tf, 0x0200, SEEK_SET );
    }
    // Read in the data
    fread( rom, 1, fsize, tf );
    fclose( tf );
    //---------------------------------//
    // Make sure it's Light Fanstasy 2 //
    //---------------------------------//
    if ( strncmp( &rom[0x118A4], "ARETHA2 VER 0.06", 16 ) ){
      ShowMessage("Error: This is not the ROM used.\n"
                  "Please load the correct ROM."
                 );
      _free( rom );
      return;
    }
    //
//    ShowMessage( "ROM loaded successfully!" );

    // Enable Text file
    LoadDataFile->Enabled = true;
    _MATH = &rom[ Snes2Pc( 0x2844A ) ];
    //
    // Build compression Labels
    decmpForm->cmList->Clear( );
    for ( int c = 0; c < fsize; c += 0x8000 )
    { //
      offset = Pc2Snes( c );
      //
      lpPosi = Snes2Pc( offset );
      valu   = WGET( rom, lpPosi );
      count  = (valu & 0xFF) >> 1;
      //
      if ( (valu & 0xFF00) == 0x8000 ){
        sprintf( buf, "Block %08X contains %3d compressed files.", offset, count );
        decmpForm->cmList->Items->Add( buf );
      }
    }

    // Try to open a Script File
    LoadDataFileClick( Sender );
    //
    if ( cmForm->bList->Items->Count <= 0 ) return;
    cmForm->bList->ItemIndex = 0;
    if ( cmForm->Visible ) cmForm->bList->SetFocus( );
    bListClick( NULL );
    //
    iCanDraw = true;

  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::SaveTextFile1Click(TObject *Sender)
{
  TxtForm->TDMemo->Lines->SaveToFile( AnsiString( txtf ) );
  ShowMessage("Text file was saved!" );
  TxtForm->TDMemo->Modified = false;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Exit1Click(TObject *Sender)
{
  Close( );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::bListClick(TObject *Sender)
{
  FILE *df;
  WORD cmpv;
  long valu;
  char buf[256],
       *p;

  if ( !ram || !rom ) return;

  for ( int i = 0; i < cmForm->bList->Items->Count; i++ )
  { //
    if ( cmForm->bList->Selected[ i ] )
    { //
      txt.ptr_posi = lpTxtBlocks[ i ];
      //
      txt.Max_ptrs = 0x100;//lpPointSize[ i ];;
      txt.posi     = i;
      // Decompress the data
      Decompress( txt.ptr_posi );

      // File the list box with data
      cmForm->pList->Clear( );
      for ( int c = 0; c < txt.Max_ptrs; c++ )
      {
        sprintf( buf, "String# %-5d", c );
        cmForm->pList->Items->Add( AnsiString( buf ) );
        //
        lpTxtPoints[ c ] = *(WORD *)&ram[ c << 1 ];
      }
      //------------------------//
      // Get new text file data //
      //------------------------//
//      sprintf( buf, "%s/Block_%02d.txt", dirc, i );
      sprintf( buf, "%s/%08X.txt", dirc, txt.ptr_posi );
      if ( FileExists( AnsiString( txtf ) ) )
      { //
        if ( TxtForm->TDMemo->Modified ){
           int k = Application->MessageBox(
             "Current data not saved. Do you wish to save it?",
             "File Modified...",
             MB_ICONQUESTION + MB_YESNO
           );
           // If yes, save the file
           if ( k == ID_YES )
             SaveTextFile1Click( NULL );
        }
      }

      // Load new data
      strcpy( txtf, buf );
      if ( FileExists( AnsiString( txtf ) ) )
        TxtForm->TDMemo->Lines->LoadFromFile( AnsiString(txtf) );
      else
      { //
        if ( !FileExists( AnsiString( buf ) ) )
        { // Create the dump Data
          df = fopen( buf, "wt" );
          if ( df )
          { //
            fprintf( df, "// Do not erase these: \n// .STRING #\n// .ENDS\n\n\n" );
            for ( int c = 0; c < txt.Max_ptrs; c++ )
              fprintf( df, ".STRING %d\n\n\n\n.ENDS\n\n\n\n", c );

            // Close the file
            fclose( df );
          }// END IF - df
        }// END IF - File exist
      }

      //
      txt.posi         = i;
      cmForm->pList->ItemIndex = 0;
      cur_str          = 0;

      cmForm->pList->Hint      = IntToStr( cmForm->pList->Items->Count ) + " item(s)";
      pListClick( NULL );
      if ( cmForm->Visible ) cmForm->bList->SetFocus( );
      TxtForm->TDMemo->Modified = false;
    }// NEXT
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::LoadDataFileClick(TObject *Sender)
{
  LONG x,y,z;
  int  cpos;
  CODE *tcode = NULL;
  char buf[560],
       cuf[560],
       arg1[32],
       arg2[32],
       var[16],
      *p;
  FILE *tf,
       *df;

  Open1->Title    = "Open Text Block Data File";
  Open1->Filter   = "Font Format File | *.txt";
  Open1->FileName = "";
  //

  if ( Open1->Execute( ) )
  { //
    tf = fopen( Open1->FileName.c_str( ), "rt" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open FONT file!");
      return;
    }

    iCanDraw       = false;
    memset(buf, 0, 256);
    cmForm->bList->Clear( );
    cpos = 0;

    // get the format data
    while( fgets( buf, 256, tf ) )
    { //----------------------//
      // Textbox color data   //
      //----------------------//
      if ( !strncmpi(buf, ".textbox", 8) )
      { //
        sscanf( buf, "%s %s", &cuf, &arg1 );
        // Get the color
        if ( strstr( buf, ".color.blue") ) Blue1->Checked   = true;
        if ( strstr( buf, ".color.green")) Green1->Checked = true;
        if ( strstr( buf, ".color.red")  ) Red1->Checked   = true;
        // Get the color type
        if ( strstr( buf, ".solid" ) )     Solid1->Checked = true;
        if ( strstr( buf, ".gradient"))    Gradient1->Checked = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".Font", 5) )
      {
        sscanf( buf, "%s %X", &cuf, &map.lpFontOffset );
      }
      //
      if ( !strncmpi(buf, ".TransText", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "SHOW" ) ){
          DTT->Checked = false;
          DTTClick( Sender );
        }
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".CONTROLCODES", 13) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "HIDE" ) ) HideCodes->Checked = false; else HideCodes->Checked = true;
        HideCodesClick( Sender );
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".VWF", 4) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "ON" ) ) UseVWFRoutine1->Checked = false; else UseVWFRoutine1->Checked = true;
        UseVWFRoutine1Click( Sender );
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".TextWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) TxtForm->Visible = false; else TxtForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".HexWindow", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) HexForm->Visible = false; else HexForm->Visible = true;
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".KanaWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) KanaForm->Visible = false; else KanaForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".FORMAT", 7) )
      { // goto _ReadGood;
        sscanf( buf, "%s   %d    %d  %d  %d   %d   %d %d %d %d",
                &buf[128],
                &map.cpl,
                &map.height,
                &map.width,
                &map.bpp,
                &map.inc,
                &map.set[0], &map.set[1],
                &map.set[2], &map.set[3]
              );
        //
        map.cpl *= map.inc;
      }
      //
      if ( !strncmpi(buf, ".BLOCK", 6) )
      { //
        sscanf( buf, "%s %X", &cuf, &x );
        //
        sprintf( buf, "Block %X", x );
        //
        lpTxtPoints[ cpos ] = 0;
        lpPointSize[ cpos ] = 0;
        lpTxtBlocks[cpos++] = x;
        //
        cmForm->bList->Items->Add( buf );
      }
      
      //---------------------------------------//
      // Check for color able index assignment //
      //---------------------------------------//
      if ( !strncmpi( buf, ".COLORTABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL=", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          {
            p = strchr( buf, '=' );
            if ( !p ) continue;
            *p = ' ';
            sscanf( buf, "%s %s", &cuf, &arg1 );
            //
            if ( !y ){
              // DUALS
              for ( int c = 0; c < 0x10000; c++ )
                if ( duals[c].type ) duals[c].color = GetIndex( arg1 );
            } else {
              // CODES
              for ( int c = 0; c < 0x00100; c++ )
                if ( codes[c].type ) codes[c].color = GetIndex( arg1 );
            }
          }
          else
          //----------------------------------//
          // Standard colors for table values //
          //----------------------------------//
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            sscanf( buf, "%X %s", &x, &arg1 );
            //
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->color = GetIndex( arg1 );
          }
          else
          if ( strstr( buf, ".ENDCOLOR" ) )
            break;
          // end if
        }
      }
      //-------------------------//
      // Load up table file data //
      //-------------------------//
      if ( !strncmpi( buf, ".TABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL ", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          { //
            sscanf( buf, "%s %s %s %s", &cuf, &arg1, &cuf, &arg2 );
            //
            int  min = GetIndex( arg1 ),
                 max = GetIndex( arg2 );
            //
            if ( min > max ){
              x   = min;
              min = max;
              max = x;
            }
            //
            for ( int c = min; c <= max; c++ )
            { //
              tcode = ( (!x) ? &codes[c] : &duals[c] );
              //
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", c );
              tcode->type = 1;  // Make this a NULL code
            }

          }
          else
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            //
            memset( cuf, 0, 256 );
            sscanf( buf, "%X %s", &x, &cuf );
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->length = strlen( cuf );
            memset( buf, 0, 256 );
            // Format string and get length
            if ( strstr( cuf, "\\x" ) )
            { //
              tcode->length = 0;
              for ( int c = 0; c < strlen( cuf ); c++ )
              { //
                if ( cuf[ c ] == '\\' && cuf[ c + 1 ] == 'x' )
                { //
                  c += 2;
                  memset( var, 0, 16 );
                  var[ 0 ] = cuf[ c++ ];
                  var[ 1 ] = cuf[ c++ ];
                  //
                  buf[ tcode->length++ ] = strtoul( var, NULL, 16 );
                }
                else
                  buf[ tcode->length++ ] = cuf[ c ];
                //
              }
              //
              memset( cuf, 0, 256 );
              memcpy( cuf, buf, tcode->length + 1 );
            }
            //
            // Set the End of text BYTE
//            cuf[ tcode->length ] = 0xFF;
            tcode->text = (BYTE *)malloc( tcode->length + 1 );
            //
            if ( !tcode->text ){
              ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
              fcloseall( ); Close( ); return;
            }
            //
            memcpy( tcode->text, cuf, tcode->length + 1 );
            //----------------------//
            // This means it's NULL //
            //----------------------//
            if ( !tcode->length )
            { //
              _free( tcode->text );
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", x );
              tcode->type = 1;  // Make this a NULL code
            }
          }
          else
          if ( strstr( buf, ".ENDTABLE" ) )
            break;
          // end if
        }
      }
    }
    // Load all block data
    fclose( tf );
    iCanDraw = true;
    //
    myForm->Caption = "Script Editor: Aretha II - [ " + ExtractFileName( Open1->FileName ) + " ]";
     // Init the first block
    cmForm->bList->ItemIndex = 0;
    cmForm->bList->Hint = IntToStr( cmForm->bList->Items->Count ) + " item(s)";
    bListClick( NULL );
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormCreate(TObject *Sender)
{
  WORD *VRAM;

  Vga = new Graphics::TBitmap;
  //
  if ( !Vga ){
    ShowMessage("Fatal Error: Could not acquire Video Pointer." );
    Close( );
    return;
  }

  // Starting directory
  getcwd( cur_dir, MAXPATH );

  Vga->Width       = Video->Width;
  Vga->Height      = Video->Height;
  Vga->PixelFormat = pf16bit;
  //
  txt.posi  = 0;
  txt.index = 0;
  //
  ScrBuf         = (WORD *)malloc( (Vga->Width * Vga->Height) << 2 );
  textbox[0].pic = (WORD *)malloc( (TBOXHEIGHT * TBOXWIDTH) << 2 );
  textbox[1].pic = (WORD *)malloc( (TBOXHEIGHT * TBOXWIDTH) << 2 );
  //
  ram = (BYTE *)malloc( 0x20000 );
  if ( !ram || !ScrBuf || !textbox[0].pic || !textbox[1].pic ){
    ShowMessage("Fatal Error: Could not allocate memory!" );
    myForm->Close( );
    return;
  }

  //
  memsetw( ScrBuf, 0x0000, Vga->Width * Vga->Height );
  memset( ram, 0, 0x20000 );
  textbox[0].height = TBOXHEIGHT;
  textbox[1].height = TBOXHEIGHT;
  //
  WinX = myForm->ClientWidth;
  WinY = myForm->ClientHeight;
  // Assign default colors to codes
  for ( int c = 0; c < 0x10000; c++ )
    codes[(c / 256)].color =
    duals[ c ].color       = 15;
  //
  for ( int y = 0; y < Vga->Height; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y ];
      memset( VRAM, 0, Vga->Width << 1);
  }
  //
  Video->Canvas->StretchDraw( Video->ClientRect, Vga );

  iCanDraw = false;
  isActive = true;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  if ( TxtForm->TDMemo->Modified )
  { //
    int k = Application->MessageBox(
      "Current data not saved. Do you wish to save it?",
      "File Modified...",
      MB_ICONQUESTION + MB_YESNO
    );
    // If yes, save the file
    if ( k == ID_YES )
      SaveTextFile1Click( NULL );
  }
  //
  _free( rom );
  _free( ram );
  _free( ScrBuf );
  _free( textbox[0].pic );
  _free( textbox[1].pic );

  for ( int c = 0; c < 0x10000; c++ )
    _free( duals[c].text );
  //
  isActive = false;

  if ( Vga ) delete Vga;
  if ( HexForm && HexForm->PIC ) delete HexForm->PIC;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::DrawText( int  skip, int height, int width )
{
  #define StartX     0
  #define StartY     0
  #define MASK_COLOR 0x11

  #define BLACK      0x00
  #define BLUE       0x01
  #define GREEN      0x02
  #define TEAL       0x03
  #define RED        0x04
  #define PURPLE     0x05
  #define BROWN      0x06
  #define GRAY       0x07

  #define CHARCOAL   0x08
  #define LtBLUE     0x09
  #define LtGREEN    0x0A
  #define LtTEAL     0x0B
  #define LtRED      0x0C
  #define LtPURPLE   0x0D
  #define YELLOW     0x0E
  #define WHITE      0x0F


  #define NONTEXT    0x0A
  #define NONTEXT2   0x0C
  #define NONTEXT3   0x04
  #define NONTEXT4   0x09
  #define NONTEXT5   0x0E
  #define DICTIONARY 0x2B

  LONG base_posi;
  LONG rom_posi;
  LONG tilep;
  LONG cpOffset;
  LONG cpTable[10] =
  {
    0x20985E,
    0x20948C,
    0x208000,
    0x20877B,
    0x208B25,
    0x208BF3,
    0x208E8C,
    0x20943C,
    0x2092A9
  };

  char buf[256];
  WORD *VRAM;
  static TBOX *myBox;
  WORD val[4];
  BYTE *TEMP    = NULL,
       COLR,
       TCOLR,
       BITS,
       BUFR[256],
       TILE[16][16],
       flag = 0,
       VWF;

  // Make sure we can do this!
  if ( !rom || !ram || !iCanDraw ) return;
  if ( !map.cpl ){
    map.cpl    = 18;
    map.height = 16;
    map.width  = 16;
    map.bpp    = 1;
    map.inc    = 16;
    map.set[0] = 0;
    map.set[1] = 1;
    map.set[2] = 2;
    map.set[3] = 3;
    map.cpl *= 8;
    //
    return;
  }

  if ( !skip )
  { // Get the Text pointer and display the text!
    myBox      = &textbox[ (int)DTT->Checked ];
    memsetw( myBox->pic, 0, 0x39000 );
    memset( &men, 0, sizeof(TMEN) );
    //
    txt.tColor = 15;
    txt.data   = 0;
    men.Ypos   = 0;
    men.Xpos   = 0;
    // Select which text box to use
    txt.xpos   = StartX;
    txt.ypos   = StartY;
    if ( !DTT->Checked ) memsetw( ScrBuf, 0, (Vga->Width * Vga->Height) );
    //----------------------------//
    // Check to see if we use the //
    // ROM or the buffer          //
    //----------------------------//
    if ( DTT->Checked )
    { //
      txt.TextBuf  = EStr;
      men.Xdim     = 36;
      myBox->width = men.Xdim << 3;
    }
    else
    { //
      txt.pntr = lpTxtPoints[ txt.ptr_index ];
      (BYTE *)txt.TextBuf = &ram[ txt.pntr ];
      //
      base_posi = (LONG)txt.TextBuf;
      men.Xdim  = map.cpl >> 3;
      // Get to the text data
      if ( !skip )
      { //
        val[0] = 0;
        while( txt.TextBuf[ 0 ] != 0x02 ){
          if ( txt.TextBuf[ 0 ] == 0x00 /*txt.TextBuf[ 0 ] == 0xFF */){
            txt.TextBuf = "Non-Text Data. Scripting Opcodes Only.\xFF";
            height = 16;
            width  = 8;
            break;
          }
          //
          if ( !_MATH[ txt.TextBuf[0] ] ){
            txt.TextBuf++;
            val[0]++;
          } else {
            txt.TextBuf += _MATH[ txt.TextBuf[0] ];
            val[0]      += _MATH[ txt.TextBuf[0] ];
          }
        }
        //
        if ( txt.TextBuf[ 0 ] == 0x02 ) txt.TextBuf++;
      } // END IF
      map.cpl       = (38 << 3);
      men.Xdim      = map.cpl >> 3;
      myBox->width  = men.Xdim << 3;
    }
    //
    if ( !DTT->Checked ){
      // Draw the hex data
      HexForm->DrawHex( txt.TextBuf );
      // Dump the text to the string viewer
      KanaForm->ShowText( txt.TextBuf, 1 );
    }
  }

  //------------------------------------//
  // Display the text data              //
  //------------------------------------//
  while( txt.data != 0xFF )
  { //
    txt.rom_posi =
    rom_posi     = txt.pntr + ((LONG)txt.TextBuf - base_posi);
    txt.data     = txt.TextBuf[0];
    txt.TextBuf += 1;

    //----------------//
    // Ditionary      //
    //----------------//
    if ( txt.data == 0xFE && (txt.TextBuf[0] > 0x00 && txt.TextBuf[0] < 0x0A) )
    { // 10 dictionary routines
        cpOffset     = Snes2Pc( cpTable[ val[0] = (txt.TextBuf[0] - 1) ]);
        txt.TextBuf += 1;
        txt.data     = txt.TextBuf[0] - 1;
        txt.TextBuf += 1;
        //
        while( txt.data )
        { //
          BITS = 0;
          while( BITS != 0xFF ){
            BITS = rom[ cpOffset ];
            cpOffset++ ;
          }
          //
          txt.data--;
        }
        //
        TEMP         = txt.TextBuf;
        txt.TextBuf  = &rom[ cpOffset ];
        //
        DrawText( (val[0]+1), map.height, map.width );
        txt.TextBuf  = TEMP;
        TEMP         = NULL;
        txt.data     = 0;
        continue;
    }

    //----------------//
    // End Text Write //
    //----------------//
    if ( txt.data == 0xFF ){
    _Break:
      txt.data = 0;
      if ( skip ) return;
      //
      if ( txt.TextBuf[0] != 0 )
      { //
        while( txt.TextBuf[ 0 ] != 0x02 ){
          if ( /*txt.TextBuf[ 0 ] == 0xFF && */txt.TextBuf[0] == 0x00 ){
//            txt.TextBuf++;
            goto _Break;
          }
         //
          if ( !_MATH[ txt.TextBuf[0] ] )
            txt.TextBuf++;
          else
            txt.TextBuf += _MATH[ txt.TextBuf[0] ];
//         txt.TextBuf += _MATH[ txt.TextBuf[0] ];
        }
        //
        txt.TextBuf++;
        continue;
      }
      else
      {
        flag = flag;
        break;
      }
    } else
    //-------------//
    // Control Codes    //
    //-------------//
    if ( txt.data == 0xFE )
    { //
      txt.data     = txt.TextBuf[0];
      txt.TextBuf += 1;
      //
      switch( txt.data )
      { // Dictionary from MEMORY
        case 0x00: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[NAME$%02X]\xff", txt.data );
                   //
                   COLR       = txt.tColor;
                   TEMP        = (BYTE *)txt.TextBuf;
                   (BYTE *)txt.TextBuf = buf;
                   //
                   DrawText( true, 16, 8 );
                   //
                   txt.tColor  = COLR;
                   (BYTE *)txt.TextBuf = TEMP;
                   TEMP        = NULL;
                   txt.data    = 0;
                   continue;
        // Keypress
        case 0x0A: sprintf( buf, "[KEY]\xff" );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Clear Screen
        case 0x0B: sprintf( buf, "[CLRSCR]\xff" );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // NewLIne
        case 0x0C: txt.data  = 0;
                   txt.ypos += height;
                   txt.xpos  = StartX;
                   men.Ydim += 2;
                   continue;
        // Fast Text
        case 0x0D: sprintf( buf, "[TEXT-HIDE]\xff" );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Clear BIT 01111111 of $03
        case 0x0E: sprintf( buf, "[TEXT-SHOW]\xff" );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Text Speed
        case 0x0F: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[TXTSPD$%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Clear BIT 11111110 of $03
        case 0x10: sprintf( buf, "[TXTSPD-NORMAL]\xff" );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //-----------------------------------------
        // Text Color White
        case 0x11: txt.tColor = WHITE;
                   continue;
        // Text Color TEAL
        case 0x12: txt.tColor = TEAL; continue;
        // Text Color Pink
        case 0x13: txt.tColor = 0x55; continue;
        // Text Color Light Blue
        case 0x14: txt.tColor = 0x35; continue;
        // Start of text per PIXEL
        case 0x15: txt.data  = txt.TextBuf[0]; txt.TextBuf += 1;
                   txt.xpos += txt.data;
//                   sprintf( buf, "[$TXT-X-MOVE$%02X] \xff", txt.data );
//                   COLR       = txt.tColor;
//                   txt.tColor = YELLOW;
//                   break;
                   continue;
        // Show CENTER Portait $xx
        case 0x16: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[2] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[PIC-CENTER_$%02X%02X%02X]\xff", val[0], val[1], val[2] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Show LEFT Portait $xx
        case 0x17: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[2] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[PIC-LEFT_$%02X%02X%02X]\xff", val[0], val[1], val[2] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Show RIGHT Portait $xx
        case 0x18: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[2] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[PIC-RIGHT_$%02X%02X%02X]\xff", val[0], val[1], val[2] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x19: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X%02X]\xff", val[0], val[1] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x1A: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X-%02X]\xff", val[0], val[1] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x1B: val[0] = txt.TextBuf[0]; txt.TextBuf += 1;
                   val[1] = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X-%02X]\xff", val[0], val[1] );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x1C: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x1D: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        //
        case 0x1E: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[$FE%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // New Text. Pointer Index = $xx
        case 0x1F: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[TEXT1-%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // New Text. Pointer Index = $xx
        case 0x20: txt.data = txt.TextBuf[0]; txt.TextBuf += 1;
                   sprintf( buf, "[TEXT2-%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
        // Exit Text
        case 0xFF: flag = flag; //if ( !txt.TextBuf[ 0 ] )
                   goto _Break;
        //--------------------------------
        default  : sprintf( buf, "[$FE%02X]\xff", txt.data );
                   COLR       = txt.tColor;
                   txt.tColor = YELLOW;
                   break;
      }
      //
      TEMP        = (BYTE *)txt.TextBuf;
//      txt.tColor  = YELLOW;
//      sprintf( buf, "[$FE%02X]\xff", txt.data );
      (BYTE *)txt.TextBuf = buf;
      //
      if ( !HideCodes->Checked )
        DrawText( true, 16, 8 );
      //
      txt.tColor  = COLR;
      (BYTE *)txt.TextBuf = TEMP;
      TEMP        = NULL;
      txt.data    = 0;
      continue;
    }
    else
    if ( (height == 16 && width == 8) || DTT->Checked )
    { //
      txt.data = (txt.data & 0x00FF);
    }
    else
    { //
      switch( skip ){
        case 0x09: txt.data &= 0x00FF; break;
        //-------------------------
        default  : txt.TextBuf -= 1; txt.data = *(WORD *)&txt.TextBuf[0]; txt.TextBuf += 2; break;
      }
      // Adjustments
      if ( !txt.data ){
        txt.xpos += 6;
        continue;
      }

      //
      if ( txt.data < 0x0100 )
        txt.data--;
      else
      if ( txt.data >= 0x0100 && txt.data < 0x0200 )
        txt.data -= 3;
      else
      if ( txt.data >= 0x0200 && txt.data < 0x0300 )
        txt.data -= 5;
      else
      if ( txt.data >= 0x0300 && txt.data < 0x0400 )
        txt.data -= 7;
      else
        txt.data -= 9;
    } // END IF


    //-----------------------------//
    // Font size testing done here //
    //-----------------------------//
//    if ( height == 16 && width == 16 )
    if ( (height == map.height && width == map.width) && !DTT->Checked )
    { // Display the text
      txt.tpos  = (txt.data * 0x20) & 0xFFFF;
      memcpy( BUFR, &rom[ Snes2Pc( 0x288000 + txt.tpos ) ], 0x20 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ x * width ], (BUFR[ x ] << 8) + BUFR[ x + 16 ], 16 );
      //
    }
    else
    //--------------------------//
    // My font used by the game //
    //--------------------------//
    if ( DTT->Checked && !skip )
    { // Last Transfer
      memcpy( BUFR, &FONT16x16[ (txt.data & 0xFF) << 5 ], 0x20 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ x << 4 ], (BUFR[ x ] << 8) + BUFR[ x + 0x10 ], 16 );
      //
    }
    else
    { // for control codes
      memcpy( BUFR, &FONT8x16[ (txt.data & 0xFF) << 4 ], 0x10 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ x << 3 ], BUFR[ x ], 8 );
      //
       if ( txt.data == 'i' )
         flag = flag;
    }

    //---------------//
    // DMA to Vram   //
    //---------------//
    VWF       = 0;
    txt.ypos %= myBox->height;
    //
    for ( int y = 0; y < height; y++ )
    { //
      for ( int x = 0; x < width; x++ )
      { //
        if ( txt.tile[ (y * width) + x ] )
        { // Add pixel
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ]     = DOS565[ txt.tColor ];
          // Add Shadow on the side
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 1) ]     = DOS565[ MASK_COLOR ];
          // Add Shadow on the bottom + side
//          myBox->pic[ ((txt.ypos + y + 1) * myBox->width) + (txt.xpos + x + 1) ] = DOS565[ MASK_COLOR ];
          // For VWF routine
          if ( x > VWF ) VWF = x;
          // For some reason single pixel
          // fonts don't record a value
          if ( !VWF ) VWF = 1;
        }
        else
        { //
          if ( myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] != DOS565[ MASK_COLOR ] )
            myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] = DOS565[ 0 ];
        }
        //
      }
    }// NEXT y

    
    //
    if ( UseVWFRoutine1->Checked || (height == 8 && width == 8) || (height == 16 && width == 8)){
      if ( !VWF ) VWF = 4;
      txt.xpos += VWF + 2;

    } else
      txt.xpos += ( (width == map.width) ? map.inc : 5 );

    // Check Width boundaries for NON-English
    if ( !DTT->Checked && txt.xpos >= (map.cpl-24) )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
      men.Ydim += 2;
    }

    // Check Width boundaries for NON-English
    if ( DTT->Checked && txt.xpos >= ((men.Xdim << 3) - 16) )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
      men.Ydim += 2;
    }
  }

  // Build Map, Draw the MenuMap, masking enabled
//  men.Ydim = ( men.Ydim > (Vga->Height>>3) ? (Vga->Height>>3) : men.Ydim );
  men.Ydim                = 14;
  men.menu[0][0]          = 1;
  men.menu[0][men.Xdim-1] = 3;
  memset( &men.menu[0][1], 2, men.Xdim - 2 );
  //
  men.menu[men.Ydim-1][0]        = 6;
  men.menu[men.Ydim-1][men.Xdim-1] = 8;
  memset( &men.menu[men.Ydim-1][1], 7, men.Xdim - 2 );
  //
  for ( int y = 1; y < men.Ydim-1; y++ )
  { //
    men.menu[y][0]        = 4;
    men.menu[y][men.Xdim-1] = 5;
  }
  //-----------------------------//
  // Which box to draw & display //
  //-----------------------------//
  if ( !DTT->Checked )
    MenuMap( &ScrBuf[(0x08 * Vga->Width) + 8], &men, Vga->Width, 0 );
  else
    MenuMap( &ScrBuf[(0x88 * Vga->Width) + 8], &men, Vga->Width, 0 );
  //
  myBox->Xpos = (DTT->Checked ? 0x88 : 0x08);
  //
  int  ypos = (DTT->Checked ? 0x88 : 0x08);
  for ( int y = 0; y < ((men.Ydim+0) << 3); y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y + myBox->Xpos ];
     memcpyw( VRAM, &ScrBuf[ (y + ypos) * Vga->Width ], Vga->Width, 0 );
  }// NEXT y
  //
  myBox->Xpos = (DTT->Checked ? 0x90 : 0x10);
  //
  for ( int y = 0; y < 96; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ (y + myBox->Xpos) ];
     // Draw the Text data
     memcpyw( &VRAM[16], &myBox->pic[ ((y + myBox->Ypos) * myBox->width) ], myBox->width, 2 );
  }// NEXT y

  Video->Canvas->StretchDraw( Video->ClientRect, Vga );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::VideoPaint(TObject *Sender)
{
  if ( rom )
//    Video->Canvas->Draw( 0, 0, Vga );
    Video->Canvas->StretchDraw( Video->ClientRect, Vga );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::pListClick(TObject *Sender)
{
  #define LINE_BREAK 0xFE0C
  #define TEXT_BREAK 0xFEFF
  #define STRING_END 0x00

  long valu,
       pos;
  WORD inPosi,
       sLen;
  char buf[256],
       tuf[256];
  char conv[16],
       flag,
       c_test,
       *p1,
       *p2;
  char *codes [ ] =
  {
    "NAME"  , "\xF4",
    "CLRSCR", "\xF5",
    "KEY"   , "\xF6",
    "COLOR" , "\xF7",
    "PAUSE" , "\xF8",
    "CHOICE", "\xFD",
    "\0"    , "\0"
  };

  if ( !ram || !rom ) return;
  //
  for ( int k = 0; k < cmForm->pList->Items->Count; k++ )
  { //
    if ( cmForm->pList->Selected[ k ] )
    { //---------------------//
      // Draw the Kana First //
      //---------------------//
      // reset scrolling positions
      if ( !TxtForm->Active ) {
        textbox[0].Ypos = 0;
        textbox[1].Ypos = 0;
      }
      //
      DTT->Checked    = false;
      txt.ptr_index   = k;
      DrawText( false, map.height, map.width );
      // Get to the string Location
      sprintf( buf, ".STRING %d", k );
      //
      KanaForm->Caption = "Kana Text: String #" + IntToStr( k );
      // Disable the Main window
      Find1->FindText  = AnsiString( buf );

      if ( (LONG)Sender == 1 )
        Find1Find( (TObject *)1 );
      else
        Find1Find( NULL );

      txt.ptr_index = k;
      //------------------------------//
      // Build translated text string //
      //------------------------------//
      if ( indexLine != -1 )
      { // Clear the buffer
        // copy text to temp buffer
        TxtForm->Memo1->Clear( );
        valu = 0;
        //
        while( Trim( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] ) != ".ENDS" )
          TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu++ ] );
        //
        TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] );
        //
        memset( EStr, 0, sizeof( EStr ) );
        inPosi = 0;
        //-------------------//
        //                   //
        //-------------------//
        for ( int i = 1; i < TxtForm->Memo1->Lines->Count; i++ )
        { //
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i ].c_str( ) );
          sLen = strlen( buf );
          // Conversion Loop
          for ( int c = 0; c < sLen; c++ )
          { //-------------------------//
            // Check for control codes //
            //-------------------------//
            if ( buf[ c ] == '[' )
            { // Get to the code
              c++;
              c_test = 0;
              flag   = 0;
              while( codes[ c_test ][ 0 ] )
              { // Do some comparisons
                if ( !strncmpi( &buf[c], codes[ c_test ], strlen( codes[ c_test ] )) &&
                     buf[ c + strlen( codes[ c_test ] ) ] == ']'
                   )
                { //
                  EStr[ inPosi++ ] = codes[ c_test + 1 ][0];
                  // Advance Testing DAta's curent position
                  c += strlen( codes[ c_test ] );
                  // If this is true, do NOT set the flag!
                  if ( buf[ c ] == '$' ) break;
                  // We found what we need! No more test
                  flag = 1;
                  //
                  break;
                } // END IF
                //
                c_test += 2;
              }

              // If FLAG still zero, no code match was found!
              if ( !flag )
              { // Check for HEX Only codes
                if ( buf[c] == '$')
                { //
                  c++;
                  while( buf[c] != ']' ){
                    memcpy( conv, &buf[c], 2 ); conv[ 2 ] = 0;
                    EStr[ inPosi++ ] = strtol( conv, NULL, 16 );
                    c += 2;
                  }

                  //
                  EStr[ inPosi ] = STRING_END;
                }
                else
                { // If it comes here then it's regular data
                  EStr[ inPosi++ ] = buf[ --c ];
                  EStr[ inPosi   ] = STRING_END;
                }
              } // END IF

            } // END IF - Control Codes
            else
            { // regular text
              EStr[ inPosi++ ] = buf[ c ];
              EStr[ inPosi   ] = STRING_END;
            } // END IF - Everything else
          }

          // Add the Line Break if needed
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i + 1 ].c_str( ) );
          if ( !strncmpi( buf, ".ENDS", 5) ){
            EStr[ inPosi++ ] = TEXT_BREAK >> 8;
            EStr[ inPosi++ ] = TEXT_BREAK & 0xFF;
            EStr[ inPosi   ] = STRING_END;
            break;
          } else {
            EStr[ inPosi++ ] = LINE_BREAK >> 8;
            EStr[ inPosi++ ] = LINE_BREAK & 0xFF;
            EStr[ inPosi   ] = STRING_END;
          }
        } // NEXT i

        //
        DTT->Checked = true;
        DrawText( false, 16, 16 );
        DTT->Checked = false;
      }

      //
      sprintf( buf, "Offset: %06X | PTR: %04X -> %06X",
                    0x7E0000 | txt.pntr,
                    txt.pntr,
                    (txt.ptr_index << 1)
             );
      //
      StatusBar1->Panels->Items[0]->Text = AnsiString( buf );
      StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
      if ( Sender && (LONG)Sender != 1 && cmForm->Visible ) cmForm->pList->SetFocus( );
      break;
    }
  }
}




//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Find1Find(TObject *Sender)
{
/*  int  StartPos,
       ToEnd,
       curLine,
       indexLine;
*/
  // begin the search after the current selection
  // if there is one
  // otherwise, begin at the start of the text
  if ( TxtForm->TDMemo->SelLength )
    StartPos = TxtForm->TDMemo->SelStart + TxtForm->TDMemo->SelLength;
  else

    StartPos = 0;

  // ToEnd is the length from StartPos
  // to the end of the text in the rich edit control

  ToEnd   = TxtForm->TDMemo->Text.Length( ) - StartPos;

  FoundAt = TxtForm->TDMemo->FindText( Find1->FindText, StartPos, ToEnd, TSearchTypes( ) );
  //

  if ( FoundAt != -1 )
  {
    TxtForm->TDMemo->SelStart  = FoundAt;
    TxtForm->TDMemo->SelLength = 0;
    //
    curLine              = TxtForm->TDMemo->Perform( EM_GETFIRSTVISIBLELINE, 0, 0 );
    if ( TxtForm->TDMemo->Text.Length( ) > 0xFFFF )
      indexLine          = TxtForm->TDMemo->Perform( EM_EXLINEFROMCHAR, FoundAt, 0 );
    else
      indexLine          = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, FoundAt, 0 );
    //
    //
    if ( (LONG)Sender != 1 )
      TxtForm->TDMemo->Perform( EM_LINESCROLL, 0, indexLine - curLine );
  }
  else
  {
    indexLine = -1;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
long __fastcall TmyForm::GetCurLine( long valu )
{
  DWORD both = 0;
  int indexLine;
  int indexLength;

  both        = MAKELPARAM( (valu >> 16) & 0xFFFF, (valu >> 0 ) & 0xFFFF );
  indexLine   = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, -1, 0 );
  indexLength = (LOWORD(both)/8) + TxtForm->TDMemo->SelLength;

  return indexLine;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayTextEditor1Click(TObject *Sender)
{
  TxtForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::HideCodesClick(TObject *Sender)
{
  HideCodes->Checked ^= 1;
  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::UseVWFRoutine1Click(TObject *Sender)
{
  UseVWFRoutine1->Checked ^= 1;
  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DTTClick(TObject *Sender)
{
  DTT->Checked ^= true;
  //
//  if ( DTT->Checked )
  pListClick( Sender );
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Red1Click(TObject *Sender)
{
  TMenuItem *m = (TMenuItem *)Sender;

  m->Checked = true;

  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Zoominx21Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY + 256;
  myForm->ClientWidth  = WinX << 1;
  //
  FormResize( NULL );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DefaultWindowSize1Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY;
  myForm->ClientWidth  = WinX;
  //
  FormResize( myForm );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayKanaTextDump1Click(TObject *Sender)
{
  KanaForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormResize(TObject *Sender)
{
  //
  if ( isActive == false ) return;
  //
  if ( myForm->WindowState == wsNormal )
  {
    TxtForm->Top  = myForm->Top;
    TxtForm->Left = myForm->Left + myForm->Width + 2;
    //
    cmForm->Top  = TxtForm->Top + TxtForm->Height + 2;;
    cmForm->Left = TxtForm->Left;
    //
    if ( Sender != NULL )
    {
      KanaForm->Left = myForm->Left;
      KanaForm->Top  = myForm->Top + myForm->Height + 2;
    }
    else
    {
      KanaForm->Left = cmForm->Left;
      KanaForm->Top  = cmForm->Top + cmForm->Height + 2;
    }
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::TEOnTopClick(TObject *Sender)
{
  TEOnTop->Checked ^= true;
  //
  if ( TEOnTop->Checked )
  {
    TxtForm->FormStyle = fsStayOnTop;
    KanaForm->FormStyle = fsStayOnTop;
  }
  else
  {
    TxtForm->FormStyle = fsNormal;
    KanaForm->FormStyle = fsNormal;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::ViewHexData1Click(TObject *Sender)
{
  HexForm->Show( );
}


//-----------------------------//
//                             //
//-----------------------------//
void __fastcall TmyForm::BuildTable( BYTE *data, WORD *ptr, LONG Size )
{
  FILE *tf;
  LONG posi;
  WORD point,
       valu;

//  memset( ptr, 0, 0x200 * sizeof(WORD));//
  for ( int c = 0; c < 0x100; c++ )
    ptr[ c ] = 0xA002;

  // Start process
  posi  = 0;
  valu  = 0;
//  point = 0xA002;
  while( posi < Size )
  { //
    if ( !data[ posi ] )
    { // Save the pointer
      posi++;
      valu = data[ posi++ ] & 0xFF;
      //
      ptr[ valu ] = 0xA000 + posi;
      // Leave routine
      if ( valu == 0xFF ) break;
    }
    else
    { // Check for other shit
      valu = _MATH[ data[posi] ];
      //
      if ( !valu )
      { // Skip test valu = $00
        while( data[posi] != 0xFF && posi < Size )
          posi++;
        //
        posi++;
        if ( posi >= Size ) break;
      }
      else
      { // Skip Test valu NOT = $00
        posi += valu;
      } // END IF Skip Test
    } // END IF - Main Test

  } // WEND
}// END OF SUB


//----------------------------------------//
// The Decompression Routine for Aretha 2 //
//----------------------------------------//
long __fastcall TmyForm::Decompress( LONG  index )
{
  LONG offset;
  WORD posi;
  BYTE *comp;
  FILE *rf;
  char buf[MAXPATH];

  offset     = Snes2Pc( index );
  WRAM(0x00) = WGET( rom, offset );
//  offset     = ((offset & 0xFF0000) | WRAM(0x00) );
  comp       = &ram[0x10000];
  // clean the memory
  memset( comp, 0, 0xFFFF );

  //-------------------------------//
  // Initialize starting variables //
  //-------------------------------//
  WRAM(0x0C) = (WRAM(0x00) & 0x7FFF) + 1;
  //
  offset    += 2;
  //----------------------------//
  // if the High bit is NOT set //
  // Store static data          //
  //----------------------------//
  if ( !(WRAM(0x00) & 0x8000) )
  { // Directly strore all static data
    WRAM(0x04) = 0x1000;				// store regular data
    while( WRAM(0x0C) > 0 )
    { //
      comp[ WRAM(0x04) ] = rom[ offset ];
      WRAM(0x04) += 1;
      WRAM(0x0C) -= 1;
      offset++;
    }//
  }
  else
  { // Start of Main Decompression Routine //
    WRAM(0x04) = 0x1000;
    WRAM(0x08) = 0x0000;
    //
    while( WRAM(0x0C) > 0 )
    { //
      ram[0x10] = rom[ offset ];
      offset++;
      ram[0x11] = 0x08;
      // loop through 8 bits
      while( ram[0x11] > 0 )
      { //
        if ( (ram[0x10] & 1) )
        { // Load and store Static Data
          comp[ WRAM(0x04) ] = rom[ offset ];
          comp[ WRAM(0x08) ] = comp[ WRAM(0x04) ];
          WRAM(0x04) += 1;
          WRAM(0x08) += 1;
          WRAM(0x08) &= 0x0FFF;
          WRAM(0x0C) -= 1;
          offset++;
        }
        else
        { // Decompress the data
          WRAM(0x00) = WGET( rom, offset );
          WRAM(0x0A) = (WRAM(0x00) & 0x0FFF);
          ram[0x0E]  = ((WRAM(0x00) >> 11) & 0x1E) + 0x03;
          offset    += 2;
          // Loop and copy
          while( ram[0x0E] > 0 )
          { //
            comp[ WRAM(0x04) ] = comp[ WRAM(0x0A) ];
            comp[ WRAM(0x08) ] = comp[ WRAM(0x0A) ];
            //
            WRAM(0x04) += 1;
            WRAM(0x08) += 1;
            WRAM(0x08) &= 0x0FFF;
            WRAM(0x0A) += 1;
            WRAM(0x0A) &= 0x0FFF;
            //
            ram[0x0E]--;
            WRAM(0x0C) -= 1;
            // Testfor end of compression
            if ( *(short *)&ram[0x0C] <= 0 ) break;
          }
        }// END IF

        // Test for end of compression
        if ( *(short *)&ram[0x0C] <= 0 ) break;
        //
        ram[0x10] >>= 1;
        ram[0x11]--;
      } // WEND - ram[0x11]
    } // END - WRAM(0x0C)
  } // END IF

  //-------------------------//
  // Build the pointer table //
  //-------------------------//
  posi = (WRAM(0x04) -= 0x1000);
  BuildTable( &comp[0x1000], (WORD *)ram, WRAM(0x04) );
  // Transfer the data to workig ram
  memcpy( &ram[0xA000], &comp[0x1000], posi );
  memmove( &comp[0x1002], &comp[0x1000], posi );
  //
  *(WORD *)&comp[0x1000] = (posi & 0xFFFF);
  //
/*
  sprintf( buf, "c:/romhack/trans/arethaII/dumps/%08X.raw", index );
  rf = fopen( buf, "wb" );
  if ( rf ){
    fwrite( ram, 1, 0x10000, rf );
    fclose( rf );
  }
/**/
  return offset;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DecompresstoFiles1Click(TObject *Sender)
{
  decmpForm->Show( );
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DumpMemory1Click(TObject *Sender)
{
  FILE *sf;

  FSave->InitialDir = cur_dir;
  FSave->Title      = "Dump Working RAM to file...";

  if ( FSave->Execute( ) )
  { //
    sf = fopen( FSave->FileName.c_str( ), "wb" );
    if ( !sf ){
      ShowMessage( "Error: Could not open file for saving..." );
      return;
    }
    //
    fwrite( ram, 1, 0x20000, sf );
    fclose( sf );
  }
}





//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  TBOX *myBox = NULL;

  if ( Shift.Contains( ssShift) ) myBox = &textbox[0];
  if ( Shift.Contains( ssCtrl ) ) myBox = &textbox[1];

  if ( myBox )
  {
    switch( Key )
    {
      case VK_UP  : if ( myBox->Ypos ) myBox->Ypos -= 16; else Key = 0; break;
      case VK_DOWN: if ( (myBox->Ypos + 96) < TBOXHEIGHT ) myBox->Ypos += 16; else Key = 0; break;
      default     : Key = 0; break;
    }
  }

  // Kana
  if ( Key )
  {
    DTT->Checked = false;
    DrawText( false, map.height, map.width);

    // Ascii
    DTT->Checked = true;
    DrawText( false, map.height, map.width );
    DTT->Checked = false;
    //
//    StatusBar1->Panels->Items[1]->Text = "Kana line: " + IntToStr( (textbox[0].Ypos >> 4) ) + " | ASCII line: " + IntToStr( (textbox[1].Ypos >> 4) );
    StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
  }
}





